package com.ruoyi.jihuo.utils;

import lombok.extern.slf4j.Slf4j;

import java.util.function.Supplier;

/**
 * @Author：HMH
 * @DATE：2025-07-26
 * @Description：重试工具类
 */
@Slf4j
public class RetryUtil {

    /**
     * 重试执行函数
     *
     * @param action      要执行的操作（返回结果）
     * @param maxAttempts 最大尝试次数
     * @param <T>         返回类型
     * @return 成功返回结果；全部失败则抛出最后一次异常
     */
    public static <T> T retry(Supplier<T> action, int maxAttempts, long sleepMillis) {
        Exception lastException = null;
        for (int i = 1; i <= maxAttempts; i++) {
            try {
                return action.get();
            } catch (Exception e) {
                lastException = e;
                log.info("第 {} 次尝试失败：{}", i, e.getMessage());
                if (i < maxAttempts && sleepMillis > 0) {
                    try {
                        Thread.sleep(sleepMillis);
                    } catch (InterruptedException ignored) {
                    }
                }
            }
        }
        throw new RuntimeException("重试失败，达到最大次数: " + maxAttempts, lastException);
    }

    /**
     * 重试执行函数
     *
     * @param action      要执行的操作（返回结果）
     * @param maxAttempts 最大尝试次数
     * @param <T>         返回类型
     * @return 成功返回结果；全部失败则抛出最后一次异常
     */
    public static <T> T retry(Supplier<T> action, int maxAttempts, long sleepMillis, String msg) {
        Exception lastException = null;
        for (int i = 1; i <= maxAttempts; i++) {
            try {
                return action.get();
            } catch (Exception e) {
                lastException = e;
                log.info("{}，第 {} 次尝试失败：{}", msg, i, e.getMessage());
                if (i < maxAttempts && sleepMillis > 0) {
                    try {
                        Thread.sleep(sleepMillis);
                    } catch (InterruptedException ignored) {
                    }
                }
            }
        }
        throw new RuntimeException("重试失败，达到最大次数: " + maxAttempts, lastException);
    }
}